﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 可视化工具.Model.自定义控件
{
    public partial class CustomBarChartControl : UserControl
    {
        private Dictionary<string, int> _data = new Dictionary<string, int>();
        private int _maxValue;
        private int _padding = 10; // Padding for the edges
        private int _leftRightPaddingPercent = 15;  // Left and right padding percent
        private int _innerPaddingPercent = 70; // Inner percentage for the bars and spacing
        private int _scaleLineOffset = 10; // 刻度线与刻度值的偏移量
        private string _hoveredText = string.Empty;  // 存储悬浮时显示的文本
        private List<Rectangle> barRectangles = new List<Rectangle>();  // 存储每个柱子的矩形区域
        private List<string> barLabels = new List<string>();  // 存储每个柱子的标签

        // 控制圆柱体圆润的角度
        public float BarCornerRadius { get; set; } = 5;

        // 控制圆柱下方文本的字体
        private Font BarLabelFont { get; set; } = GetCustomFont("Arial", 6); // 使用自定义字体类

        // 控制圆柱下方文本的颜色
        private Color BarLabelColor { get; set; } = Color.Black;

        // 控制圆柱体上方文本的字体
        private Font BarTopLabelFont { get; set; } = GetCustomFont("Arial", 8); // 使用自定义字体类

        // 控制圆柱体上方文本的颜色
        private Color BarTopLabelColor { get; set; } = Color.Blue;

        // 控制左侧刻度的字体
        private Font ScaleFont { get; set; } = GetCustomFont("Arial", 8); // 使用自定义字体类

        // 控制左侧刻度的颜色
        private Color ScaleFontColor { get; set; } = Color.Green;

        // 变量来存储当前悬停的柱子信息
        private string _hoveredLabel = null;
        private Rectangle _hoveredBarRect;
        private Point _hoveredTextPosition;
        public CustomBarChartControl()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
            _maxValue = 1;
            this.MouseMove += CustomBarChartControl_MouseMove;  // 鼠标移动事件
            this.MouseLeave += CustomBarChartControl_MouseLeave;  // 鼠标离开时隐藏文本
        }

        public Dictionary<string, int> Data
        {
            get { return _data; }
            set
            {
                _data = value;
                _maxValue = Math.Max(0, GetMaxValue()); // 防止小于 0 的情况
                Invalidate();
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            try
            {
                base.OnPaint(e);

                if (_data.Count == 0) return;

                // 计算可用宽度
                int availableWidth = this.Width - 2 * _padding;

                // 计算留白部分
                int leftPadding = (int)(availableWidth * (_leftRightPaddingPercent / 100.0)); // 15% for the left side
                int rightPadding = leftPadding; // 15% for the right side

                // 剩余的宽度用于圆柱和留白
                int remainingWidth = availableWidth - leftPadding - rightPadding;

                // 计算每个项的宽度和留白的宽度
                int itemCount = _data.Count;
                int totalSpacingWidth = remainingWidth - (_innerPaddingPercent * itemCount / 100);
                int barWidth = totalSpacingWidth / itemCount;

                // 如果总宽度超出了控件的宽度，按比例缩小宽度
                int totalWidth = itemCount * barWidth + (itemCount - 1) * (_innerPaddingPercent * remainingWidth / 100);
                if (totalWidth > this.Width - _padding * 2) // 如果总宽度超出控件的宽度
                {
                    float scaleFactor = (float)(this.Width - _padding * 2) / totalWidth;
                    barWidth = (int)(barWidth * scaleFactor);
                }

                // 绘制 L 形刻度线
                DrawLShapeAxes(e.Graphics);

                // 绘制左侧刻度
                DrawScale(e.Graphics);

                int x = _padding + leftPadding;
                int totalValue = GetTotalValue();

                // 清空之前的柱子区域记录
                barRectangles.Clear();
                barLabels.Clear();

                // 绘制柱状图和顶部文本
                foreach (var entry in _data)
                {
                    // 计算柱状图高度
                    int barHeight = _maxValue > 0 ? (int)((double)entry.Value / _maxValue * (this.Height - 40)) : 0;

                    // 绘制圆润的柱子
                    Rectangle barRectangle = new Rectangle(x + 5, this.Height - barHeight - 30, barWidth - 10, barHeight);
                    barRectangles.Add(barRectangle); // 记录柱子区域
                    barLabels.Add(entry.Key); // 记录柱子标签

                    DrawRoundedRectangle(e.Graphics, Brushes.Red, x + 5, this.Height - barHeight - 30, barWidth - 10, barHeight, BarCornerRadius);

                    // 绘制柱子下方的标签
                    using (Brush labelBrush = new SolidBrush(BarLabelColor))
                    {
                        e.Graphics.DrawString(entry.Key, BarLabelFont, labelBrush, x + 5, this.Height - 20);
                    }

                    // 绘制顶部文本，包括值和百分比
                    double percentage = totalValue > 0 ? (double)entry.Value / totalValue * 100 : 0;
                    using (Brush topLabelBrush = new SolidBrush(BarTopLabelColor))
                    {
                        e.Graphics.DrawString($"{entry.Value} ({percentage:F2}%)", BarTopLabelFont, topLabelBrush, x + 5 + barWidth / 3, this.Height - barHeight - 35);
                    }

                    // 更新x坐标位置
                    x += barWidth + (remainingWidth / 100 * _innerPaddingPercent) / itemCount;
                }
                if (!string.IsNullOrEmpty(_hoveredLabel))
                {
                    using (Brush hoveredTextBrush = new SolidBrush(Color.Black))
                    {
                        e.Graphics.DrawString(_hoveredLabel, BarTopLabelFont, hoveredTextBrush, _hoveredTextPosition);
                    }
                }
            }
            catch
            {
            }
        }

        /// <summary>
        /// 获取自定义字体，保证字体大小不小于1pt
        /// </summary>
        public static Font GetCustomFont(string familyName, float size)
        {
            try
            {
                // 确保字体大小不小于1pt
                size = Math.Max(size, 1f);
                return new Font(familyName, size);
            }
            catch
            {
                return new Font(familyName,size);
            }
        }

        /// <summary>
        /// 绘制左侧刻度
        /// </summary>
        private void DrawScale(Graphics graphics)
        {
            try
            {
                int steps = _maxValue; // 步数与最大值一致
                if (_maxValue == 0)
                {
                    // 如果最大值为 0，只显示 0
                    using (Brush scaleBrush = new SolidBrush(ScaleFontColor))
                    {
                        graphics.DrawString("0", ScaleFont, scaleBrush, _padding / 2, this.Height - 20);
                    }
                    return;
                }

                // 计算刻度间隔高度
                int scaleHeight = this.Height - 40; // 刻度区域高度
                int stepHeight = scaleHeight / steps;

                // 绘制刻度值
                for (int i = 0; i <= steps; i++)
                {
                    int y = this.Height - 20 - i * stepHeight;
                    using (Brush scaleBrush = new SolidBrush(ScaleFontColor))
                    {
                        graphics.DrawString(i.ToString(), ScaleFont, scaleBrush, _padding / 2, y);
                    }

                    // 绘制刻度线
                    using (Pen pen = new Pen(ScaleFontColor, 2))
                    {
                        graphics.DrawLine(pen, _padding + _scaleLineOffset, y + 5, _padding + _scaleLineOffset + 10, y + 5);
                    }
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// 绘制 L 形刻度线
        /// </summary>
        private void DrawLShapeAxes(Graphics graphics)
        {
            try
            {
                using (Pen pen = new Pen(ScaleFontColor, 2))
                {
                    // 绘制左侧竖线
                    graphics.DrawLine(pen, _padding + _scaleLineOffset, _padding, _padding + _scaleLineOffset, this.Height - 20);

                    // 绘制底部横线
                    graphics.DrawLine(pen, _padding + _scaleLineOffset, this.Height - 20, this.Width - _padding, this.Height - 20);
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// 获取总值
        /// </summary>
        private int GetTotalValue()
        {
            try
            {
                return _data.Values.Sum();
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 获取最大值
        /// </summary>
        private int GetMaxValue()
        {
            try
            {
                return _data.Count > 0 ? _data.Values.Max() : 0;
            }
            catch
            {
                return 0;
            }
        }



        // 处理鼠标离开时隐藏文本
        private void CustomBarChartControl_MouseLeave(object sender, EventArgs e)
        {
            try
            {
                _hoveredLabel = null;
                Invalidate(); // 重新绘制
            }
            catch
            {

            }
        }
        /// <summary>
        /// 绘制带圆角的矩形
        /// </summary>
        public void DrawRoundedRectangle(Graphics g, Brush brush, int x, int y, int width, int height, float cornerRadius)
        {
            try
            {
                // 使用一个圆角矩形路径来绘制矩形
                using (GraphicsPath path = new GraphicsPath())
                {
                    // 添加圆角矩形路径
                    path.AddArc(x, y, cornerRadius, cornerRadius, 180, 90); // 左上角圆角
                    path.AddArc(x + width - cornerRadius, y, cornerRadius, cornerRadius, 270, 90); // 右上角圆角
                    path.AddArc(x + width - cornerRadius, y + height - cornerRadius, cornerRadius, cornerRadius, 0, 90); // 右下角圆角
                    path.AddArc(x, y + height - cornerRadius, cornerRadius, cornerRadius, 90, 90); // 左下角圆角
                    path.CloseFigure();

                    // 用刷子填充路径
                    g.FillPath(brush, path);
                }
            }
            catch
            {

            }
        }
        private void CustomBarChartControl_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                _hoveredLabel = null;

                // 遍历每个柱子区域，检查鼠标是否悬浮在柱子上
                for (int i = 0; i < barRectangles.Count; i++)
                {
                    if (barRectangles[i].Contains(e.Location))
                    {
                        // 计算当前柱子的百分比
                        double percentage = GetTotalValue() > 0 ? (double)_data[barLabels[i]] / GetTotalValue() * 100 : 0;
                        _hoveredLabel = $"{barLabels[i]}: {_data[barLabels[i]]} ({percentage:F2}%)";
                        _hoveredBarRect = barRectangles[i];

                        // 计算文本的水平居中位置
                        int textWidth = (int)Graphics.FromImage(new Bitmap(1, 1)).MeasureString(_hoveredLabel, BarTopLabelFont).Width;
                        int centerX = _hoveredBarRect.Left + (_hoveredBarRect.Width - textWidth) / 2;
                        int centerY = _hoveredBarRect.Top + (_hoveredBarRect.Height - BarTopLabelFont.Height) / 2;

                        _hoveredTextPosition = new Point(centerX, centerY);

                        Invalidate(); // 重新绘制
                        return;
                    }
                }

                _hoveredLabel = null; // 如果鼠标不在任何柱子上
            }
            catch
            {

            }
        }

    }

}
